package testrj.runner;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import rjson.Rjson;
import rjson.printer.Printer;
import rjson.transformer.AbstractTransformer;
import testrj.domain.MethodToTest;
import testrj.domain.TestrjConfig;

public class TestRunner {
	private String testReferenceName;
	private MethodToTest methodToTest;

	public void runTestCase() {
		try {
			Object objectUnderTest = methodToTest.getObjectForObjectUnderTest();
			Method methodUnderTest = methodToTest.getMethodToTest();
			Object actualResult = methodUnderTest.invoke(objectUnderTest, methodToTest.getInputParamsAsOrignialObjects().toArray());

			methodToTest.currentTestCase().getAsserter().assertEquals(methodToTest.getReturnValueAsOriginalObject(), actualResult);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public MethodToTest getMethodToTest() {
		return methodToTest;
	}

	public void prepareToRunTestCaseId(int id) {
		methodToTest.prepareToRunTestCaseId(id);
	}

	public static TestRunner instantiateRunnerFor(String testReferenceName) {
		return instantiateRunnerFor(testReferenceName, 0);
	}

	public static TestRunner instantiateRunnerFor(String testReferenceName, String id) {
		return instantiateRunnerFor(testReferenceName, Integer.parseInt(id));
	}

	public static TestRunner instantiateRunnerFor(String testReferenceName, int id) {
		TestRunner runner = new TestRunner();
		runner.testReferenceName = testReferenceName;
		runner.methodToTest = (MethodToTest) TestrjConfig.persister.getSingleDataSet(testReferenceName, false);
		runner.methodToTest.prepareToRunTestCaseId(id);
		return runner;
	}

	private TestRunner() {
	}
}

class DateTransformer extends AbstractTransformer {
	public boolean canHandle(Object object) {
		if (object instanceof java.util.Date)
			return true;
		return false;
	}

	public void transform(Object object, Printer printer, Rjson rjson) {
		printData(null, printer);
	}
}